package com.hu.bgp.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.hu.bgp.client.widgets.GameInstanceTable;
import com.hu.bgp.client.widgets.GameTypeTableUser;
import com.hu.bgp.framework.util.FailureHandler;
import com.hu.bgp.framework.util.FailureHandlingCallback;
import com.hu.bgp.shared.BoardGameService;
import com.hu.bgp.shared.BoardGameServiceAsync;
import com.hu.bgp.shared.ClientGameInstance;
import com.hu.bgp.shared.ClientGameInstanceCollection;
import com.hu.bgp.shared.ClientGameType;
import com.hu.bgp.shared.ClientGameTypeCollection;

/**
 * De normale GUI voor het selecteren van een spelletje.
 * 
 * @author ejvos
 */
public class PlayerClient implements EntryPoint, FailureHandler
{
	private BoardGameServiceAsync bgpService;
	private ClientGameType currentGameType;
	private ClientGameInstance currentGameInstance;
	private final Button selectGameTypeButton = new Button("Select game type");
	private final Button joinGameButton = new Button("Join game");
	private final Button createNewGameButton = new Button("Create new game");
	private final GameTypeTableUser gameTypeTable = new GameTypeTableUser();
	private final GameInstanceTable gameInstanceTable = new GameInstanceTable();
	private final HorizontalPanel loginMessage = new HorizontalPanel();
	private final TextBox nameBox = new TextBox();
	private final Button loginButton = new Button("set name");
	private final Label nameLabel = new Label();

	public void onModuleLoad()
	{
		// get a binding to the servlet
		bgpService = GWT.create(BoardGameService.class);
		ServiceDefTarget target = (ServiceDefTarget) bgpService;
		// zie ook BgpConfiguration.getPlayerClientUrlPrefix
		target.setServiceEntryPoint("/bgp/bgpService");

		// grab a collection of gametypes
		bgpService.getClientGameTypeCollection(new FailureHandlingCallback<ClientGameTypeCollection>(this)
		{
			public void onSuccess(ClientGameTypeCollection result)
			{
				for (ClientGameType gameType : result)
				{
					gameTypeTable.addGameRow(gameType);
				}
			}
		});

		// add some login controls
		loginMessage.add(nameLabel);
		loginMessage.add(nameBox);
		loginMessage.add(loginButton);

		bgpService.getProfileName(new FailureHandlingCallback<String>(PlayerClient.this)
		{
			public void onSuccess(String result)
			{
				if (result != null)
				{
					nameLabel.setText("Welcome back, " + result);
				}
			}
		});

		loginButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				bgpService.setProfileName(nameBox.getText(), new FailureHandlingCallback<Void>(PlayerClient.this)
				{
					public void onSuccess(Void result)
					{
					}
				});
			}
		});

		selectGameTypeButton.addClickHandler(new SelectGameTypeHandler());
		joinGameButton.addClickHandler(new JoinGameHandler());
		createNewGameButton.addClickHandler(new CreateNewGameHandler());

		RootPanel.get("gameTypeTable").add(gameTypeTable);
		RootPanel.get("actionButtons").add(selectGameTypeButton);
		RootPanel.get("loginMessage").add(loginMessage);
	}

	private class CreateNewGameHandler implements ClickHandler
	{
		public void onClick(ClickEvent event)
		{
			bgpService.createNewGameInstance(currentGameType.getAlias(), new FailureHandlingCallback<ClientGameInstance>(PlayerClient.this)
			{
				public void onSuccess(ClientGameInstance result)
				{
					currentGameInstance = result;
					gameInstanceChanged();
				}
			});
		}
	}

	private class JoinGameHandler implements ClickHandler
	{
		public void onClick(ClickEvent event)
		{
			currentGameInstance = gameInstanceTable.getSelection();
			bgpService.joinGame(currentGameType.getAlias(), currentGameInstance.getId(), new FailureHandlingCallback<String>(PlayerClient.this)
			{
				public void onSuccess(String result)
				{
					gameInstanceChanged();
				}
			});
		}
	}

	private class SelectGameTypeHandler implements ClickHandler
	{
		public void onClick(ClickEvent event)
		{
			currentGameType = gameTypeTable.getSelection();
			gameTypeChanged();
		}
	}

	private void gameTypeChanged()
	{
		RootPanel.get("gameTypeTable").remove(gameTypeTable);
		RootPanel.get("actionButtons").remove(selectGameTypeButton);

		// grab a collection of game instances
		bgpService.getClientGameInstanceCollection(currentGameType.getAlias(), new FailureHandlingCallback<ClientGameInstanceCollection>(this)
		{
			public void onSuccess(ClientGameInstanceCollection result)
			{
				for (ClientGameInstance instance : result)
				{
					gameInstanceTable.addGameInstanceRow(instance);
				}
			}
		});

		RootPanel.get("gameTypeTable").add(gameInstanceTable);
		RootPanel.get("actionButtons").add(joinGameButton);
		RootPanel.get("actionButtons").add(createNewGameButton);
	}

	private void gameInstanceChanged()
	{
		// FIXME
		// TODO
		RootPanel content = RootPanel.get("content");
		content.getElement().setInnerHTML("");

		Element body = RootPanel.getBodyElement();
		Element head = body.getParentElement().getFirstChildElement();

		Element script = DOM.createElement("script");
		script.setAttribute("type", "text/javascript");
		script.setAttribute("language", "javascript");
		script.setAttribute("src", "/resources/" + currentGameType.getAlias() + "/" + currentGameType.getAlias() + ".nocache.js");
		head.appendChild(script);
	}

	public void onFailure(Throwable caught)
	{
		caught.printStackTrace();
	}
}
